/* model */
import { ConnectorModuleComponentNameEnum, ConnectorPaasDataStorageKey } from '@src/modules/connector/model'
import { BaseWindowSizeEnum } from '@src/component/common/BaseWindow'
/* scss */
import '@src/modules/connector/components/paas-iframe-dialog/index.scss'
/* vue */
// @ts-ignore
import { ComponentInstance, ComponentRenderProxy, computed, defineComponent, PropType, Ref, ref } from 'vue'
import { CommonComponentInstance } from '@model/VC'
import { CreateElement } from 'vue'
/* hooks */
import { useDialog } from '@hooks/useDialog'
import { useLoading } from '@hooks/useLoading'
/* types */
import { ConnectorInsertSelectCallParams } from '@src/modules/connector/types'
/* util */
import { parse } from '@src/util/lang/object'
import Log from '@src/util/log'
import { getTabIdByConnectorJumpUrl } from '@src/modules/connector/util'

export type ConnectorModulePaasIframeDialogProps = {
  appId: string;
  formId: string;
  formContentId: string;
  processorInstanceId: string;
  isDetail: boolean;
  url: string;
  messageData: ConnectorInsertSelectCallParams;
}

export interface ConnectorModulePaasIframeDialogSetupState {
  
}

export enum ConnectorModulePaasIframeDialogEmitEventNameEnum {
  Input = 'input',
  Success = 'success',
  GetID = 'getId',
}

export type ConnectorModulePaasIframeDialogInstance = ComponentInstance & ConnectorModulePaasIframeDialogSetupState

export type ConnectorModulePaasIframeDialogMethodsOptions = {
  open: (title: string) => void;
}

export type ConnectorModulePaasIframeDialogVM = ComponentRenderProxy<ConnectorModulePaasIframeDialogProps, {}, {}, {}, ConnectorModulePaasIframeDialogMethodsOptions> & CommonComponentInstance & ConnectorModulePaasIframeDialogInstance

const PaasIframeDialogRef = 'PaasIframeDialogComponent'
const PaasIframeDialogId = 'PaasIframeDialog'

export default defineComponent({
  name: ConnectorModuleComponentNameEnum.ConnectorModulePaasIframeDialog,
  emits: [
    ConnectorModulePaasIframeDialogEmitEventNameEnum.Input,
    ConnectorModulePaasIframeDialogEmitEventNameEnum.Success,
    ConnectorModulePaasIframeDialogEmitEventNameEnum.GetID,
  ],
  props: {
    appId: {
      type: String as PropType<string>,
      default: ''
    },
    formId: {
      type: String as PropType<string>,
      default: ''
    },
    formContentId: {
      type: String as PropType<string>,
      default: ''
    },
    messageData: {
      type: Object as PropType<ConnectorInsertSelectCallParams>,
      default: () => ({})
    },
    processorInstanceId: {
      type: String as PropType<string>,
      default: ''
    },
    isDetail: {
      type: Boolean,
      default: false
    },
    url: {
      type: String as PropType<string>,
      default: ''
    }
  },
  setup(props: ConnectorModulePaasIframeDialogProps, { emit }) {
    
    const { visible: insideVisible, showDialog, hideDialog } = useDialog()
    const { loading, showLoading, hideLoading } = useLoading()
    
    const title = ref('')
    const size = ref(BaseWindowSizeEnum.Larger)
    
    const iframeUrl = computed(() => props.url)
    
    const connectorStorageData: Ref<Partial<ConnectorInsertSelectCallParams>> = ref({})
    
    const onCloseWindowHandler = () => {
      hideDialog()
      hideLoading()
    }
    
    return {
      insideVisible,
      showDialog,
      hideDialog,
      
      loading,
      showLoading,
      hideLoading,
      
      iframeUrl,
      title,
      size,
      connectorStorageData,
      
      onCloseWindowHandler
      
    }
  },
  computed: {
    iframeClassNames() {
      const tabUrl = getTabIdByConnectorJumpUrl(this.iframeUrl)
      return [tabUrl]
    }
  },
  watch: {
    iframeUrl() {
      this.$nextTick(()=> {
        
        const paasIframeElement = document.getElementById(PaasIframeDialogId) as HTMLFrameElement | null
        
        if (paasIframeElement && paasIframeElement.contentWindow) {
          paasIframeElement.contentWindow.location.reload(true)
        }
        
      })
    }
  },
  mounted() {
    this.onWindowMessageHandler()
  },
  methods: {
    /** 
    * @description 获取属性列表
    */
    getAttributes() {
      return {
        ref: PaasIframeDialogRef,
        props: {
          className: 'connector-module-paas-iframe-dialog-window',
          title: this.title,
          size: this.size,
          show: this.insideVisible,
        },
        on: {
          'getId': (id: string) => {
            this.$emit(ConnectorModulePaasIframeDialogEmitEventNameEnum.GetID, id)
          },
          'closed': () => {
            this.onCloseWindowHandler()
            // 从sessionStorage中移除连接器信息
            this.removeConnectDataSessionStorage()
          },
          'update:show': () => {
            this.onCloseWindowHandler()
          },
        },
        directives: [
          {
            name: 'loading',
            value: this.loading
          }
        ]
      }
    },
    getConnectDataToSessionStorage() {
      const connectorData = sessionStorage.getItem(ConnectorPaasDataStorageKey) || ''
      return parse(connectorData)
    },
    removeConnectDataSessionStorage() {
      sessionStorage.removeItem(ConnectorPaasDataStorageKey)
    },
    /** 
     * @description 关闭 paas 模块页面事件
    */
    onPassIframeLoadHandler() {
      this.hideLoading()
    },
    onWindowMessageHandler() {
      window.addEventListener('message', (event) => {
        
        const data = event.data
        
        // 监听到子页面关闭
        if(data?.close) {
          
          Log.info(data, this.onWindowMessageHandler.name, this.onWindowMessageHandler.name)
          
          this.onCloseWindowHandler()
          this.onSuccessHandler()
        }
        
        // 子页面刷新
        if(data?.refresh) {
          
          Log.info(data, this.onWindowMessageHandler.name, this.onWindowMessageHandler.name)
          
          this.onSuccessHandler()
          
        }
        
        // 监听子页面加载完
        if (data?.ready) {
          
          Log.info(data, this.onWindowMessageHandler.name, this.onWindowMessageHandler.name)
          
          const paasIframeElement = document.getElementById(PaasIframeDialogId) as HTMLFrameElement | null
          
          const connectorStorageData = this.getConnectDataToSessionStorage()
          
          const isSamePage = connectorStorageData?.toBizTypeId == this.messageData?.toBizTypeId
          
          console.log(' window.addEventListener ~ isSamePage', isSamePage)
          
          // 发送工单数据
          if (paasIframeElement && paasIframeElement.contentWindow && isSamePage) {
            
            paasIframeElement.contentWindow.postMessage({ 
              
              task: {},
              connector: {
                ...this.messageData
              }
              
            }, '*');
            
          }
          
          this.hideLoading()
          
        }
        
      })
    },
    onSuccessHandler() {
      this.$nextTick(() => {
        this.$emit(ConnectorModulePaasIframeDialogEmitEventNameEnum.Success)
      })
    },
    open(title: string) {
      
      this.title = title
      
      this.showLoading()
      this.showDialog()
      
      this.$nextTick(()=> {
        
        const baseWindowComponent = this.$refs[PaasIframeDialogRef] as any
        
        if (baseWindowComponent.showBaseWindow) {
          baseWindowComponent.restoreWindow()
        }
        
      })
      
    },
  },
  render(h: CreateElement) {
    
    const attrs = this.getAttributes()
    
    return (
      <base-window {...attrs} >
        <div class="paas-iframe-dialog-container">
          <iframe
            frameborder="0"
            width="100%"
            height="100%"
            id={PaasIframeDialogId}
            src={this.iframeUrl}
            onLoad={this.onPassIframeLoadHandler}
            class={this.iframeClassNames}
          />
        </div>
      </base-window>
    )
  }
})
